package com.atguigu.gulimall.product.service.impl;
import com.atguigu.gulimall.product.dao.SkuSaleAttrValueDao;
import com.atguigu.gulimall.product.dao.SpuInfoDao;
import com.atguigu.gulimall.product.entity.SkuImagesEntity;
import com.atguigu.gulimall.product.entity.SpuInfoDescEntity;
import com.atguigu.gulimall.product.entity.SpuInfoEntity;
import com.atguigu.gulimall.product.service.SkuImagesService;
import com.atguigu.gulimall.product.service.SpuInfoDescService;
import com.atguigu.gulimall.product.vo.SkuItemSaleAttrVo;
import com.atguigu.gulimall.product.vo.SkuItemVo;
import com.atguigu.gulimall.product.vo.SpuItemAttrGroupVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.product.dao.SkuInfoDao;
import com.atguigu.gulimall.product.entity.SkuInfoEntity;
import com.atguigu.gulimall.product.service.SkuInfoService;
@Service("skuInfoService")
@Slf4j
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {
    @Autowired
    private SkuImagesService skuImagesService;
    @Autowired
    private SpuInfoDescService spuInfoDescService;
    @Autowired
    private SpuInfoDao spuInfoDao;
    @Autowired
    private SkuSaleAttrValueDao skuSaleAttrValueDao;
    @Autowired
    private ThreadPoolExecutor executor;
    @Override
    public SkuItemVo getItemBySkuId(Long skuId) throws ExecutionException, InterruptedException {
        SkuItemVo skuItemVo = new SkuItemVo();
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            //我编排一个异步任务，根据skuId拿到该sku实体类，因为这个结果后面的方法要用，所以我需要用supplyAsync方法
            //1、sku基本信息的获取  pms_sku_info   private SkuInfoEntity info; private boolean hasStock = true;
            SkuInfoEntity skuInfoEntity =this.baseMapper.selectById(skuId);
            skuItemVo.setInfo(skuInfoEntity);
            return skuInfoEntity;
        }, executor);
        //infoFuture异步编排任务完成后，再进行并行执行 thenAcceptAsync的作用
        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            //3、获取spu的销售属性组合  private List<SkuItemSaleAttrVo> saleAttr;
            List<SkuItemSaleAttrVo> saleAttr = this.skuSaleAttrValueDao.getSaleAttrValueInThisSpu(res.getSpuId());
            skuItemVo.setSaleAttr(saleAttr);
        }, executor);
        CompletableFuture<Void> spuInfoDescFuture = infoFuture.thenAcceptAsync((res) -> {
            //4、获取spu的介绍  private SpuInfoDescEntity desc;
            LambdaQueryWrapper<SpuInfoDescEntity> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(SpuInfoDescEntity::getSpuId,res.getSpuId());
            SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getBaseMapper().selectOne(wrapper1);
            skuItemVo.setDesc(spuInfoDesc);
        }, executor);
        CompletableFuture<Void> groupAttrsFuture = infoFuture.thenAcceptAsync((res) -> {
            //5、获取spu的规格参数信息  private List<SpuItemAttrGroupVo> groupAttrs;
            List<SpuItemAttrGroupVo> groupAttrs = spuInfoDao.querySpuItemAttrGroupVoList(res.getCatalogId(), res.getSpuId());
            skuItemVo.setGroupAttrs(groupAttrs);
        }, executor);
        CompletableFuture<Void> skuImagesFuture = CompletableFuture.runAsync(() -> {
            //2、sku的图片信息    pms_sku_images    private List<SkuImagesEntity> images;
            LambdaQueryWrapper<SkuImagesEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SkuImagesEntity::getSkuId, skuId);
            List<SkuImagesEntity> skuImagesList = skuImagesService.getBaseMapper().selectList(wrapper);
            skuItemVo.setImages(skuImagesList);
        }, executor);
        //.get();主线程需要阻塞，直到上面几个异步编排任务都要完成后再执行
        CompletableFuture.allOf(saleAttrFuture,spuInfoDescFuture,groupAttrsFuture,skuImagesFuture).get();
        return skuItemVo;
    }
    @Override
    public List<SkuInfoEntity> getSkuInfoBySpuId(Long spuId) {
       return baseMapper.selectList(new LambdaQueryWrapper<SkuInfoEntity>()
                .eq(SkuInfoEntity::getSpuId,spuId));
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
//        IPage<SkuInfoEntity> page = this.page(
//                new Query<SkuInfoEntity>().getPage(params),
//                new QueryWrapper<SkuInfoEntity>()
//        );
        Query<SkuInfoEntity> query = new Query<>();
        //得到了一个分页对象，里面封装了当前页和每页记录数
        IPage<SkuInfoEntity> page = query.getPage(params);
        LambdaQueryWrapper<SkuInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
        String key=(String)params.get("key");
        String catelogId = (String) params.get("catelogId");
        String brandId =(String) params.get("brandId");
        String min =(String) params.get("min");
        String max =(String) params.get("max");
        if (StringUtils.isNotEmpty(key)){
            //(spuid=xx or spuname=xxx) 这里要用and
            //queryWrapper.eq(SpuInfoEntity::getId,key).or().like(SpuInfoEntity::getSpuName,key);
            queryWrapper.and((obj)->{
                obj.eq(SkuInfoEntity::getSkuId,key).or().like(SkuInfoEntity::getSkuName,key);
            });
        }
        if (StringUtils.isNotEmpty(catelogId) && !"0".equalsIgnoreCase(catelogId)){
            queryWrapper.and((obj)->{
                obj.eq(SkuInfoEntity::getCatalogId,catelogId);
            });
        }
        if (StringUtils.isNotEmpty(brandId)&&!"0".equalsIgnoreCase(brandId)){
            queryWrapper.and((obj)->{
                obj.eq(SkuInfoEntity::getBrandId,brandId);
            });
        }
        if (StringUtils.isNotEmpty(min)){
            try {
                BigDecimal less = new BigDecimal(min);
                queryWrapper.and((obj)->{
                    obj.ge(SkuInfoEntity::getPrice,less);
                });
            }catch (Exception e){
                log.error("前端sku检索价格最小值不是数",e);
            }
        }
        if (StringUtils.isNotEmpty(max)){
            try {
                BigDecimal great = new BigDecimal(max);
                queryWrapper.and((obj)->{
                    obj.le(SkuInfoEntity::getPrice,great);
                });
            }catch (Exception e){
                log.error("前端sku检索价格最大值不是数",e);
            }
        }
        IPage<SkuInfoEntity> iPage = this.page(page, queryWrapper);
        return new PageUtils(iPage);
    }

    @Override
    public void saveSkuInfo(SkuInfoEntity skuInfoEntity) {
        baseMapper.insert(skuInfoEntity);
    }

}